// web/src/actions/login.ts
'use server';
import * as z from 'zod'
import {LoginSchema} from "@/schemas";
import {signIn} from "@/auth";
import {DEFAULT_LOGIN_REDIRECT} from "@/routes";
import {getUserByEmail} from "@/data/user";
import {generateVerificationToken, generateTwoFactorToken} from "@/data/tokens";
import {sendTwoFactorTokenEmail, sendVerificationEmail} from "@/lib/mail";
import {AuthError} from "next-auth";
import {getTwoFactorTokenByEmail} from '@/data/two-factor-token';
import {db} from '@/lib/db';
import {getTwoFactorConfirmationByUserId} from "@/data/two-factor-confirmation";

export const login = async (values: z.infer<typeof LoginSchema>) => {
    // 校验
    const validatedFields = LoginSchema.safeParse(values)

    if (!validatedFields.success) {
        return {error: "Invalid fields!"}
    }

    const {email, password, code} = validatedFields.data

    const existingUser = await getUserByEmail(email)
    if (!existingUser || !existingUser.email || !existingUser.password) {
        // 非数据库登录的要用其他provider
        return {error: "Email does not exist!"}
    }

    // 第一次登录要邮件验证
    if (!existingUser.emailVerified) {
        const verificationToken = await generateVerificationToken(existingUser.email)

        await sendVerificationEmail(
            verificationToken.email,
            verificationToken.token
        )

        return {success: 'Confirmation email sent!'}
    }

    // 双因素验证
    if (existingUser.isTwoFactorEnable && existingUser.email) {
        if (code) {
            // 验证双因素code
            const twoFactorToken = await getTwoFactorTokenByEmail(existingUser.email)
            if (!twoFactorToken) {
                return {error: "Invalid code!"}
            }
            if (twoFactorToken.token !== code) {
                return {error: "Invalid code!"}
            }

            const hasExpired = new Date(twoFactorToken.expires) < new Date()
            if (hasExpired) {
                return {error: "Code expired!"}
            }

            await db.twoFactorToken.delete({
                where: {id: twoFactorToken.id}
            })

            // 更新2FA验证信息
            const existingConfirmation = await getTwoFactorConfirmationByUserId(
                existingUser.id
            )
            if (existingConfirmation) {
                await db.twoFactorConfirmation.delete({
                    where: {id: existingConfirmation.id}
                })
            }

            await db.twoFactorConfirmation.create({
                data: {
                    userId: existingUser.id
                }
            })
        } else {
            // 开启2FA后第一次登录, 新增code并发送邮件
            const twoFactorToken = await generateTwoFactorToken(existingUser.email)
            await sendTwoFactorTokenEmail(
                twoFactorToken.email,
                twoFactorToken.token
            )

            return {twoFactor: true}
        }
    }

    try {
        // 重定向错误???
        await signIn('credentials', {email, password, redirectTo: DEFAULT_LOGIN_REDIRECT})
        // await signIn('credentials', {email, password, redirect: false})
        // return {success: "Login success!"}
    } catch (err) {
        // if (err instanceof AuthError) {
        //     switch (err.type) {
        //         case 'CredentialsSignin':
        //             return {error: 'Invalid credentials!'}
        //         case 'AccessDenied':
        //             return {error: 'Access denied!'}
        //         default:
        //             return {error: 'Something went wrong!'}
        //     }
        // }
        if (err instanceof AuthError) {
            // @ts-ignore
            switch (err.type) {
                case 'CredentialsSignin':
                    return {error: 'Invalid credentials!'}
                default:
                    return {error: 'Something went wrong!'}
            }
        }

        throw err
    }
    return {success: "login success"}
}